﻿using System.Globalization;
using DataClasses;

namespace CYPlayer.ViewModel
{
    using System;
    using System.Windows.Input;
    using NAudio.Wave;
    using global::ViewModel;

    public class PlayerWindowVM : ViewModelBase
    {
        #region Members

        private SongVM _selectedSong;
        private BlockAlignReductionStream _stream;
        private DirectSoundOut _output;
        private double _maximumValue = 1;
        private string _maxValue = "0";
        private TimeSpan _currentPosition = new TimeSpan(0,0,0);

        #endregion

        #region Properties

        public TimeSpan MinimumValue
        {
            get{return new TimeSpan(0,0,0);}
        }

        public double MaximumValue
        {
            get
            {
                return _maximumValue;
            }
            set
            {
                _maximumValue = value;
                RaisePropertyChanged("MaximumValue");
            }
        }

        public string MaxValue
        {
            get { return _maxValue; }
            set 
            { 
                _maxValue = value;
                RaisePropertyChanged("MaxValue");
            }
        }

        public TimeSpan CurrentPosition
        {
            get
            {
                _currentPosition = _stream.CurrentTime;
                return _currentPosition;
            }
            set
            {
                _currentPosition = value;
                RaisePropertyChanged("CurrentPosition");
            }
        }

        public SongVM SelectedSong
        {
            get
            {
                return _selectedSong;
            }

            set
            {
                _selectedSong = value;
                MaximumValue = Song.ConvertSpan(_selectedSong.Duration);
                MaxValue = MaximumValue.ToString();
                DisposeWave();
                RaisePropertyChanged("SelectedSong");
            }
        }

        #endregion

        #region Commands

        void PlayFileExecute()
        {
            if (_output != null)
            {
                if (_output.PlaybackState != PlaybackState.Playing)
                {
                    _output.Play();
                }
                else if (_output.PlaybackState == PlaybackState.Playing)
                {
                    _output.Pause();
                }

                return;
            }

            DisposeWave();
            var path = _selectedSong.Song.Path;
            if (path.EndsWith(".mp3"))
            {
                var pcm = WaveFormatConversionStream.CreatePcmStream(new Mp3FileReader(path));
                _stream = new BlockAlignReductionStream(pcm);
            }
            else if (path.EndsWith(".wav"))
            {
                WaveStream pcm = new WaveChannel32(new WaveFileReader(path));
                _stream = new BlockAlignReductionStream(pcm);
            }
            else
            {
                throw new InvalidOperationException("Not a correct audio file type.");
            }

            _output = new DirectSoundOut();
            _output.Init(_stream);
            _output.Play();
        }

        public ICommand PlayFile
        {
            get
            {
                return new RelayCommand(p => PlayFileExecute());
            }
        }

        private void DisposeWave()
        {
            if (_output != null)
            {
                if (_output.PlaybackState == PlaybackState.Playing) _output.Stop();

                _output.Dispose();
                _output = null;
            }

            if (_stream == null) return;

            _stream.Dispose();
            _stream = null;
        }
        #endregion
    }
}
